package com.rephilo.code.service;

import com.rephilo.code.constant.CodeConstant;
import com.rephilo.code.feign.EmailRemoteService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.RedisConnectionFailureException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class CodeService {

    private static final Logger logger = LoggerFactory.getLogger(CodeService.class);

    private final Random random = new Random();

    private static final Integer EXPIRE_TIME = 10 * 60 * 1000;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private EmailRemoteService emailRemoteService;

    /**
     * 生成验证码，并发送邮件
     *
     * @param email
     * @return
     */
    public Boolean create(String email) {
        //确认缓存中是否已存在当前邮箱的验证码
        String cache = redisTemplate.opsForValue().get(email);
        //不存在则创建，有效期10分钟
        if (cache == null) {
            String code = randomCode();
            boolean flag = emailRemoteService.sendEmail(email, "验证码", code);
            if (flag) {
                redisTemplate.opsForValue().set(email, code, EXPIRE_TIME, TimeUnit.MILLISECONDS);
            }
        }

        return true;
    }

    /**
     * 校验验证码是否正确
     *
     * @param email
     * @param code
     * @return
     */
    public Integer validate(String email, String code) {
        try {
            String cache = redisTemplate.opsForValue().get(email);
            if (cache != null && cache.equals(code)) {
                return CodeConstant.VALIDATE_SUCCESS;
            }
        } catch (RedisConnectionFailureException e) {
            logger.error("validate failed param is {}, {}, message is : ", email, code, e);
            return CodeConstant.VALIDATE_TIME_OUT;
        }

        return CodeConstant.VALIDATE_FAIL;
    }

    /**
     * 建议使用
     */
    private String randomCode() {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            str.append(random.nextInt(10));
        }
        return str.toString();
    }
}
